home *** CD-ROM | disk | FTP | other *** search
/ Utilities Professional 1-1500 / Utilities Professional 1-1500 (1994)(WPD)[!].iso / 12511500 / var1450.dms / var1450.adf / TrackdiskDevice / Example3.c < prev    next >
C/C++ Source or Header  |  1992-04-27  |  15KB  |  492 lines

  1. /***********************************************************/
  2. /*                                                         */
  3. /* Amiga C Encyclopedia (ACE) V3.0      Amiga C Club (ACC) */
  4. /* -------------------------------      ------------------ */
  5. /*                                                         */
  6. /* Book:    ACM Devices                 Amiga C Club       */
  7. /* Chapter: Trackdisk Device            Tulevagen 22       */
  8. /* File:    Example3.c                  181 41  LIDINGO    */
  9. /* Author:  Anders Bjerin               SWEDEN             */
  10. /* Date:    92-04-27                                       */
  11. /* Version: 1.00                                           */
  12. /*                                                         */
  13. /*   Copyright 1992, Anders Bjerin - Amiga C Club (ACC)    */
  14. /*                                                         */
  15. /* Registered members may use this program freely in their */
  16. /*     own commercial/noncommercial programs/articles.     */
  17. /*                                                         */
  18. /***********************************************************/
  19.  
  20.  
  21.  
  22. /* This example demonstrates how you can read data with help of the   */
  23. /* Trackdisk Device. You give this program four arguments (drive,     */
  24. /* head, cylinder and sector), and it will print out all data in that */
  25. /* sector. You only have to expand this program a little and you will */
  26. /* end up with a nice disk viewer.                                    */
  27. /*                                                                    */
  28. /* Use: Example3 drive (0-3) head (0-1) cylinder (0-79) sector (0-10) */
  29.  
  30.  
  31.  
  32. #include <exec/types.h>        /* Datatypes         */
  33. #include <exec/ports.h>        /* Messages          */
  34. #include <exec/errors.h>       /* IO Error          */
  35. #include <exec/memory.h>       /* Allocating memory */
  36. #include <devices/trackdisk.h> /* Trackdisk Device  */
  37.  
  38.  
  39.  
  40. /* Motor status: */
  41. #define OFF  0
  42. #define ON   1
  43.  
  44. /* Help text: */
  45. #define HELP "Use: Example3 drive (0-3) head (0-1) cylinder (0-79) sector (0-10)"
  46.  
  47. /* Buffer size (512 bytes): */
  48. #define BUFFERSIZE TD_SECTOR
  49.  
  50.  
  51.  
  52. /* Declare a pointer to our reply port: */
  53. struct MsgPort *replymp;
  54.  
  55. /* Declare a pointer to an IOExtTD structure: */
  56. struct IOExtTD *exreq;
  57.  
  58. /* Have we opened the Trackdisk Device? */
  59. BOOL device_open = FALSE;
  60.  
  61. /* Pointer to our memory buffer: */
  62. BYTE *buffer;
  63.  
  64. /* Disk change value: */
  65. ULONG disk_change_count;
  66.  
  67.  
  68.  
  69. /* Declare our functions: */
  70. void main();
  71. void clean_up( BYTE error, STRPTR text );
  72. BYTE DiskMotor( BYTE status );
  73. void TrackdiskError( BYTE error );
  74. ULONG DiskChangeCount( void );
  75. BYTE ReadDisk( WORD head, WORD cylinder, WORD sector );
  76. void PrintTrackdiskData( void );
  77.  
  78.  
  79.  
  80. void main( int argc, char *argv[] )
  81. {
  82.   /* Was the motor already on or not? */
  83.   BYTE motor_was_on;
  84.  
  85.   /* Error number: */
  86.   BYTE error;
  87.  
  88.   /* Store the four arguments in these variables: */
  89.   int drive, head, cylinder, sector;
  90.  
  91.  
  92.  
  93.   /* Process the arguments: */
  94.   /* If not 4 arguments + program name, error: */
  95.   if( argc != 5 )
  96.     clean_up( 0, HELP );
  97.   else
  98.   {
  99.     /* Convert to integer: */
  100.     drive = atoi( argv[1] );
  101.     head = atoi( argv[2] );
  102.     cylinder = atoi( argv[3] );
  103.     sector = atoi( argv[4] );
  104.  
  105.     /* Check the values: */
  106.     if( drive < 0 || drive > 3 ||        /* Drive:    0 -  3 */
  107.         head < 0 || head > 1 ||          /* Head:     0 -  1 */
  108.         cylinder < 0 || cylinder > 79 || /* Cylinder: 0 - 79 */
  109.         sector < 0 || sector > 10 )      /* Sector:   0 - 10 */
  110.       clean_up( 0, HELP );
  111.   }
  112.  
  113.  
  114.  
  115.   /* Get a reply port: */
  116.   replymp = (struct MsgPort *)
  117.     CreatePort( NULL, 0 );
  118.   if( !replymp )
  119.     clean_up( 0, "Could not create the reply port!" );
  120.  
  121.  
  122.  
  123.   /* Create an IOExtTD structure: */
  124.   exreq = (struct IOExtTD *)
  125.     CreateExtIO( replymp, sizeof( struct IOExtTD ) );
  126.   if( !exreq )
  127.     clean_up( 0, "Could not create the IO!" );
  128.  
  129.  
  130.  
  131.   /* Open the Trackdisk Device: */
  132.   error = OpenDevice( TD_NAME, drive, exreq, 0 );
  133.   if( error )
  134.     clean_up( error, "Could not open the Trackdisk Device!" );
  135.   else
  136.     device_open = TRUE;
  137.  
  138.  
  139.  
  140.   /* Allocate memory for our disk buffer: (Must be Chip Memory!) */
  141.   buffer = (BYTE *) AllocMem( BUFFERSIZE, MEMF_CHIP | MEMF_CLEAR );
  142.   if( !buffer )
  143.     clean_up( 0, "Could not allocate enough memory for the buffer!" );
  144.  
  145.  
  146.  
  147.   /* Get the disk's change count value: (We can later compare */
  148.   /* this number with the disk's cout value later on, and if  */
  149.   /* they are not equal, the disk has been removed and/or     */
  150.   /* changed!)                                                */
  151.   disk_change_count = DiskChangeCount();
  152.  
  153.  
  154.  
  155.   /* Turn the motor on: Well, we do not actually need to do this,   */
  156.   /* since it will automatically be turned on when we start to      */
  157.   /* read. However, it takes some micro seconds to "tune" the drive */
  158.   /* when it is turned on so if you are going to write several      */
  159.   /* times to the drive you better keep it on. Note that once the   */
  160.   /* motor is on you must turn it off yourself! (Unless it was      */
  161.   /* already on.)                                                   */
  162.   motor_was_on = DiskMotor( ON );
  163.  
  164.  
  165.  
  166.   /* Print some information: */
  167.   printf( "Diskdrive: df%d:\n", drive );
  168.   printf( "Head:      %d\n", head );
  169.   printf( "Cylinder:  %d\n", cylinder );
  170.   printf( "Sector:    %d\n", sector );
  171.  
  172.  
  173.  
  174.   /* Try to read one sector: */
  175.   if( error = ReadDisk( head, cylinder, sector ) )
  176.     TrackdiskError( error ); /* ERROR! */
  177.   else
  178.     PrintTrackdiskData();    /* OK! */
  179.  
  180.  
  181.  
  182.   /* Only if the motor was off before we turned it on should */
  183.   /* we turn it off again. If the motor was already on we    */
  184.   /* should not turn it off since that means that some other */
  185.   /* task wants it to be on.                                 */
  186.   if( !motor_was_on )
  187.     DiskMotor( OFF );
  188.  
  189.  
  190.  
  191.   /* Clean up and quit: */
  192.   clean_up( 0, "The End!" );
  193. }
  194.  
  195.  
  196.  
  197. /* Close and return everything that has been */
  198. /* opened and  allocated before we quit:     */
  199.  
  200. void clean_up( BYTE error, STRPTR text )
  201. {
  202.   if( error )
  203.     TrackdiskError( error );
  204.   
  205.   /* Free buffer: */
  206.   if( buffer )
  207.     FreeMem( buffer, BUFFERSIZE );
  208.  
  209.   /* Close the Trackdisk Device: */ 
  210.   if( device_open )
  211.     CloseDevice( exreq );
  212.  
  213.   /* Delete the IOExtTD structure: */
  214.   if( exreq )
  215.     DeleteExtIO( exreq, sizeof( struct IOExtTD ) );
  216.  
  217.   /* Remove the replyport: */
  218.   if( replymp )
  219.     DeletePort( replymp);
  220.  
  221.   /* Print the message: */
  222.   printf( "%s\n", text );
  223.  
  224.   /* Quit: */
  225.   exit( 0 );
  226. }
  227.  
  228.  
  229.  
  230. /* DiskMotor() will turn on/off the diskdrive's motor.  */
  231. /*                                                      */
  232. /* Synopsis:  oldstatus = DiskMotor( new_status );      */
  233. /*                                                      */
  234. /* oldstatus: (BYTE) DiskMotor() returns 1 if the motor */
  235. /*            was already on, else 0 (motor was off).   */
  236. /*                                                      */
  237. /* newstatus: (BYTE) Set this field to 1 (ON) if you    */
  238. /*            want to turn the motor on, else set it to */
  239. /*            0 (OFF) and the motor will be turned off. */
  240. /*            Note! If you turned the motor on when the */
  241. /*            motor was off you must turn it off before */
  242. /*            your program terminates. However, if it   */
  243. /*            was already on you should not turn it     */
  244. /*            off.                                      */
  245.  
  246. BYTE DiskMotor( BYTE status )
  247. {
  248.   /* Will the user what we will do: */
  249.   printf( "Motor will be turned: %s\n", status ? "On" : "Off" );
  250.  
  251.   /* Set our request: */
  252.   exreq->iotd_Req.io_Command = TD_MOTOR; /* Turn motor on/off. */ 
  253.   exreq->iotd_Req.io_Length = status;    /* 0 = off, 1 = on.   */
  254.  
  255.   /* Do our request, and return when done: */
  256.   DoIO( exreq );
  257.  
  258.   /* DoIO() will return when it has done our request, */
  259.   /* so it will therefore not send us any message to  */
  260.   /* our reply port. If we had used SendIO() instead  */
  261.   /* (returns immediately) we would had to wait for a */
  262.   /* message to arrive at our reply port.             */
  263.  
  264.   /* Check if the motor was on or not before we changed it: */
  265.   printf( "Motor was: %s\n", exreq->iotd_Req.io_Actual ? "On" : "Off" );
  266.  
  267.   /* Return 1 if the motor was already on, 0 if not: */
  268.   return( (BYTE) exreq->iotd_Req.io_Actual );
  269. }
  270.  
  271.  
  272.  
  273. /* TrackdiskError() will give the user some more information */
  274. /* about the error.                                          */
  275. /*                                                           */
  276. /* Synopsis: TrackdiskError( error );                        */
  277. /*                                                           */
  278. /* error:    (BYTE) Give this function the error value, and  */
  279. /*           it will give the user some more information     */
  280. /*           about the error.                                */
  281.  
  282. void TrackdiskError( BYTE error )
  283. {
  284.   printf( "Error code: %d\n", error );
  285.   printf( "Problem: " );
  286.  
  287.   /* The complete list of possible errors: */
  288.   switch( error )
  289.   {
  290.     case TDERR_NotSpecified:
  291.       printf( "Something, we do not know what, failed!\n" );
  292.       break;
  293.  
  294.     case TDERR_NoSecHdr:
  295.       printf( "Could not find a sector!\n" );
  296.       break;
  297.  
  298.     case TDERR_BadSecPreamble:
  299.       printf( "The sector is corrupted!\n" );
  300.       break;
  301.  
  302.     case TDERR_BadSecID:
  303.       printf( "Problems with identifying the sector!\n" );
  304.       break;
  305.  
  306.     case TDERR_BadHdrSum:
  307.       printf( "The header had incorrect checksum!\n" );
  308.       break;
  309.  
  310.     case TDERR_BadSecSum:
  311.       printf( "The sector had incorrect checksum!\n" );
  312.       break;
  313.  
  314.     case TDERR_TooFewSecs:
  315.       printf( "There are too few sectors!\n" );
  316.       break;
  317.  
  318.     case TDERR_BadSecHdr:
  319.       printf( "The sector's header is corrupted!\n" );
  320.       break;
  321.  
  322.     case TDERR_WriteProt:
  323.       printf( "The disk is write protected!\n" );
  324.       break;
  325.  
  326.     case TDERR_DiskChanged:
  327.       printf( "No disk present or disk changed!\n" );
  328.       break;
  329.  
  330.     case TDERR_SeekError:
  331.       printf( "Could not find track 0!\n" );
  332.       break;
  333.  
  334.     case TDERR_NoMem:
  335.       printf( "Not enough memory!\n" );
  336.       break;
  337.  
  338.     case TDERR_BadUnitNum:
  339.       printf( "Requested diskdrive does not exist!\n" );
  340.       break;
  341.  
  342.     case TDERR_BadDriveType:
  343.       printf( "The Trackdisk Device can not handle that diskdrive!\n" );
  344.       break;
  345.  
  346.     case TDERR_DriveInUse:
  347.       printf( "The requested diskdrive is already used by someone else!\n" );
  348.       break;
  349.  
  350.     case TDERR_PostReset:
  351.       printf( "Oh no! The user hit the reset buttons, we are going down!\n" );
  352.       break;
  353.  
  354.  
  355.     /* The standard device errors: */
  356.  
  357.     case IOERR_OPENFAIL:
  358.       printf( "Could not open the device!\n" );
  359.       break;
  360.  
  361.     case IOERR_ABORTED:
  362.       printf( "The request was aborted!\n" );
  363.       break;
  364.       
  365.     case IOERR_NOCMD:
  366.       printf( "Not a valid command! Not supported by the trackdisk device!\n" );
  367.       break;
  368.       
  369.     case IOERR_BADLENGTH:
  370.       printf( "Bad length or value!\n" );
  371.       break;
  372.  
  373.     default:
  374.       /* Unknown error value: */
  375.       printf( "What? Unknown error code!\n" );
  376.   }
  377. }
  378.  
  379.  
  380.  
  381. /* DiskChangeCount() returns the current disk's "count value". */
  382. /* If the value has changet we know that the disk has been     */
  383. /* removed and/or changed.                                     */
  384. /*                                                             */
  385. /* Synopsis: count = DiskChangeCount();                        */
  386. /*                                                             */
  387. /* count:    (ULONG) The disk's "change count value".          */
  388.  
  389. ULONG DiskChangeCount( void )
  390. {
  391.   /* Get the disk's change count value: */
  392.   exreq->iotd_Req.io_Command = TD_CHANGENUM;
  393.  
  394.   /* Do our request, and return when completed: */
  395.   DoIO( exreq );
  396.   
  397.   /* Return the answer: */
  398.   return( (ULONG) exreq->iotd_Req.io_Actual );
  399. }
  400.  
  401.  
  402.  
  403. /* ReadDisk() will start to read at a specific sector, until */
  404. /* the diskbuffer is filled. (In this example we only read   */
  405. /* one sector.                                               */
  406. /*                                                           */
  407. /* Synopsis: error = ReadDisk( head, cylinder, sector );     */
  408. /*                                                           */
  409. /* error:    (BYTE) ReadDisk() returns 0 if everything was   */
  410. /*           OK, else an error number is returned. Use our   */
  411. /*           function TrackdiskError() to find out what went */
  412. /*           wrong.                                          */
  413. /*                                                           */
  414. /* head:     (WORD) Which head should be used. [0-1]         */
  415. /*                                                           */
  416. /* cylinder: (WORD) Start at this cylinder. [0-79]           */
  417. /*                                                           */
  418. /* sector:   (WORD) Start at this sector. [0-10]             */
  419.  
  420. BYTE ReadDisk( WORD head, WORD cylinder, WORD sector )
  421. {
  422.   /* We want to read: */
  423.   exreq->iotd_Req.io_Command = ETD_READ;
  424.  
  425.   /* Pointer to our buffer: */
  426.   exreq->iotd_Req.io_Data = (APTR) buffer;
  427.  
  428.   /* Read until the buffer is filled: */
  429.   exreq->iotd_Req.io_Length = BUFFERSIZE;
  430.  
  431.   /* Set current disk count value: (If the value has changed */
  432.   /* this request will be canceled.)                         */
  433.   exreq->iotd_Count = disk_change_count;
  434.  
  435.   /* Start to read at position: (The diskdrive has 2 heads, 80 */
  436.   /* cylinders which each consists of 11 (NUMSECS) sectors,    */
  437.   /* with 512 (TD_SECTOR) usable bytes of data each.)          */ 
  438.   exreq->iotd_Req.io_Offset = (LONG)
  439.    TD_SECTOR*( NUMSECS * 2 * cylinder + NUMSECS * head + sector );
  440.  
  441.   /* Do our request, and return when completed: */
  442.   DoIO( exreq );
  443.  
  444.   /* Return error value: (0: OK, else ERROR) */
  445.   return( (BYTE) exreq->iotd_Req.io_Error );
  446. }
  447.  
  448.  
  449.  
  450. /* PrintTrackdiskData() prints out the data which we have put */
  451. /* in the buffer. The left side of the screen is filled with  */
  452. /* the data in hexadecimal form, while on the right side you  */
  453. /* can see what it represents in ASCII codes.                 */
  454. /*                                                            */
  455. /* Synopsis: PrintTrackdiskData();                            */ 
  456.  
  457. void PrintTrackdiskData( void )
  458. {
  459.   /* Temporary buffer pointer: */
  460.   UBYTE *ptr;
  461.   int x, y;
  462.  
  463.  
  464.   /* Start at the beginning of the buffer: */
  465.   ptr = buffer;
  466.   /* Print out the whole buffer: */
  467.   for( y = 0; y < BUFFERSIZE / 16; y++ )
  468.   {
  469.     /* The first 8 bytes in hexadecimal form: */
  470.     printf( "%02X: %02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,", y,
  471.       ptr[0], ptr[1], ptr[2], ptr[3],
  472.       ptr[4], ptr[5], ptr[6], ptr[7] );
  473.  
  474.     /* The following 8 bytes in hexadecimal form: */
  475.     printf( "%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X | ",
  476.       ptr[8], ptr[9], ptr[10], ptr[11],
  477.       ptr[12], ptr[13], ptr[14], ptr[15] );
  478.  
  479.     /* If the value is between 32 (!) and 126 (~) we print out the */
  480.     /* character, else we print a space:                           */ 
  481.     for( x = 0; x < 16; x++ )
  482.       printf( "%1c", ( ptr[ x ] > 31 && ptr[ x ] < 127 ) ? ptr[ x ] : ' ' );
  483.  
  484.     /* Next line: */
  485.     printf( "\n" );
  486.  
  487.     /* Next 16 bytes: */
  488.     ptr += 16;
  489.   }
  490. }
  491.  
  492.